/**
 * @Auther: ChenforCode
 * @Date: 2018/9/11 21:50
 * @Description:
 */
package cn.chenforcode.dao;

import cn.chenforcode.entity.Student;
import oracle.jdbc.OracleType;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate5.SessionFactoryUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.sql.CallableStatement;
import java.sql.SQLException;
import java.util.List;

@Repository
@Transactional
public class StudentDAO {
    @Autowired
    private SessionFactory sessionFactory;

    public Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 向学生表中插入一个新学生
     * @Date 21:52 2018/9/11
     * @Param [student]
     **/
    public void addStudent(Student student) {
        this.getSession().save(student);
    }

    /**
     * @return int
     * @Author ChenforCode
     * @Description //TODO 判断是否可以插入
     * @Date 21:53 2018/9/11
     * @Param [sno]
     **/
    public int queryCanAdd(String sno) {
        CallableStatement statement = null;
        int retValue = 0;
        try {
            statement = SessionFactoryUtils.getDataSource(sessionFactory)
                    .getConnection().prepareCall("{call querystcanadd(?,?)}");
            statement.setString(1, sno);
            statement.registerOutParameter(2, OracleType.NUMBER);
            statement.execute();

            retValue = statement.getInt(2);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            return retValue;
        }
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 根据学号删除一个学生
     * @Date 21:54 2018/9/11
     * @Param [sno]
     **/
    public void deleteStudentBySno(String sno) {
        this.getSession().createQuery("delete Student where sno = ?1")
                .setParameter(1, sno).executeUpdate();
    }

    /**
     * @return int
     * @Author ChenforCode
     * @Description //TODO 判断是否可以删除这个学生
     * @Date 21:55 2018/9/11
     * @Param [sno]
     **/
    public int queryCanDelete(String sno) {
        CallableStatement statement = null;
        int retValue = 0;
        try {
            statement = SessionFactoryUtils.getDataSource(sessionFactory)
                    .getConnection().prepareCall("{call querystcandel(?,?)}");
            statement.setString(1, sno);
            statement.registerOutParameter(2, OracleType.NUMBER);
            statement.execute();

            retValue = statement.getInt(2);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            return retValue;
        }
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 更新学生信息
     * @Date 21:55 2018/9/11
     * @Param [student]
     **/
    public void updateStudent(Student student) {
        this.getSession().update(student);
    }

    /**
     * @return java.util.List<cn.chenforcode.entity.Student>
     * @Author ChenforCode
     * @Description //TODO 得到所有的学生信息
     * @Date 21:56 2018/9/11
     * @Param []
     **/
    public List<Student> getAllStudents() {
        return this.getSession().createQuery("from Student").list();
    }

    /**
     * @return cn.chenforcode.entity.Student
     * @Author ChenforCode
     * @Description //TODO 根据学号获得学生对象
     * @Date 21:58 2018/9/11
     * @Param [sno]
     **/
    public Student getStudentBySno(String sno) {
        return (Student) this.getSession().createQuery("from Student where sno = ?1")
                .setParameter(1, sno).uniqueResult();
    }

    /**
     * @return void
     * @Author ChenforCode
     * @Description //TODO 充值账户
     * @Date 8:34 2018/9/14
     * @Param [sno, add]
     **/
    public void addBanance(String sno, long add) {
        Student student = getStudentBySno(sno);
        student.setBalance(student.getBalance() + add);
        updateStudent(student);
    }
}
